#include "event/loop.hpp"
#include "fmt/core.h"
#include "network/sockaddr.hpp"
#include "network/stdio_stream.hpp"
#include "network/tcp_connection.hpp"
#include "network/tcp_connector.hpp"

using namespace std;
using namespace ibox::event;
using namespace ibox::network;
// 实现了一个客户端, 服务端(nc -l -p xxx)和客户端可以互相发送数据
int main() {
    SockAddr server_addr = SockAddr::from_string("127.0.0.1:8080");
    auto loop = Loop();

    StdioStream stdio(&loop);
    stdio.enable();

    TcpConnector connector{&loop};
    connector.initialize(server_addr);
    connector.set_connected_callback([&](TcpConnection *new_conn) {
        // 注意new_conn指针使用值传递方式
        new_conn->set_disconnected_callback([&, new_conn]() {
            fmt::print("connection disconnected: {} !!!\n",
                       new_conn->peer_addr()->to_string());
            delete new_conn;
            loop.stop();
        });
        new_conn->bind(&stdio); // tcp数据往终端输出
        stdio.bind(new_conn);   // 终端的输入往tcp输出
    });
    // 设置连接重试次数
    connector.set_try_times(3);
    connector.set_connect_fail_callback([&] {
        fmt::print("connect to server {} failed!\n", server_addr.to_string());
        loop.stop();
    });
    connector.start();

    if (server_addr.type() == SockAddr::Type::IPv4) {
        IpAddress ip;
        uint16_t port = 0;
        server_addr.get(ip, port);
        fmt::print("try command: nc -l -p {}\n", port);
    }
    loop.run();
}
